package sk.naive.talker.command;

import sk.naive.talker.*;
import sk.naive.talker.props.*;
import sk.naive.talker.message.DefaultMessageFactory;
import sk.naive.talker.persistence.PersistenceException;
import sk.naive.talker.util.Utils;

import java.rmi.RemoteException;
import java.util.*;

/**
 * Look displays current location (room) with its description, users in, etc.
 *
 * @author <a href="mailto:virgo@naive.deepblue.sk">Richard "Virgo" Richter</a>
 * @version $Revision: 1.32 $ $Date: 2005/03/21 21:45:49 $
 */
public class Look extends AbstractCommand {
	private StringBuilder stringBuffer = new StringBuilder();
	private Location location;

	public void exec() throws RemoteException, CommandException, PropertyStoreException {
		location = new LocationHelper(commandDispatcher).locationForUser(user);
		if (location == null) {
			sendHelper().sendMessage(user, "message.noRoom");
			return;
		}
		appendDescription();
		appendUsersInRoom();
		appendExits();
		appendTopic();
		user.send(stringBuffer.toString());
	}

	private void appendDescription() throws CommandException {
		ctxSet(DefaultMessageFactory.CTXKEY_VAL + "Room", location.getProperties());
		try {
			ctxSet(DefaultMessageFactory.CTXKEY_VAL, location.description());
		} catch (PersistenceException e) {
			throw new CommandException(e);
		}
		stringBuffer.append(getString("look.desc", user.getProperties()));
	}

	private void appendUsersInRoom() throws PropertyStoreException {
		Set<User> users = new TreeSet<User>(new Comparator() {
			public int compare(Object o1, Object o2) {
				return ((User) o1).getLogin().compareTo(((User) o2).getLogin());
			}
		});
		users.addAll(location.users());

		if (users.size() > 1) {
			stringBuffer.append(getString("look.usersInLabel", user.getProperties()));
			for (Iterator i = users.iterator(); i.hasNext(); ) {
				User lookedUser = (User) i.next();
				if (lookedUser == user) {
					continue;
				}
				long current = System.currentTimeMillis();
				long lastAction = (Long) lookedUser.get(User.UPROP_LAST_ACTION_TIME);
				AfkStatus afkStatus = new AfkHelper(lookedUser).getStatus();
				if (afkStatus != null) {
					lastAction = afkStatus.getAfkStart();
					if (afkStatus.getReason() != null) {
						ctxSet(lookedUser, DefaultMessageFactory.CTXKEY_VAL + "AfkReason", afkStatus.getReason());
					}
				}
				long afkTime = Utils.createLong(current - lastAction, Consts.MINUTE_MILLIS);
				if (afkStatus != null || afkTime >= 10) {
					ctxSet(lookedUser, DefaultMessageFactory.CTXKEY_VAL + "AfkTime", afkTime);
				}
				stringBuffer.append(getString("look.userLine", lookedUser.getProperties(), user.getLang()));
			}
			stringBuffer.append(getString("look.usersInTail", user.getProperties()));
		} else {
			stringBuffer.append(getString("look.noOtherUser", user.getProperties()));
		}
	}

	private void appendExits() {
		boolean isSuperuser = Utils.ownsPermission(user, Consts.PERM_SUPERUSER);
		boolean isRoomAdmin = Utils.ownsPermission(user, RoomAdmin.PERM_ROOM_ADMIN);
		boolean isOwner = location.getLocationOwners().contains(user.getId());
		Set nearLocs = location.nearLocations();
		if (nearLocs.size() > 0) {
			Set exitNames = new TreeSet();
			for (Iterator i = nearLocs.iterator(); i.hasNext(); ) {
				Location loc = (Location) i.next();
				if (isSuperuser || isRoomAdmin || isOwner || BooleanProperty.booleanValue((String) loc.get(Location.LPROP_VISIBILITY))) {
					exitNames.add(loc.getName());
				}
			}
			if (exitNames.size() > 0) {
				ctxSet(DefaultMessageFactory.CTXKEY_VAL, Utils.formatCollection(exitNames, ", "));
				stringBuffer.append(getString("look.exits", user.getProperties()));
			} else {
				stringBuffer.append(getString("look.noExit", user.getProperties()));
			}
		} else {
			stringBuffer.append(getString("look.noExit", user.getProperties()));
		}
	}

	private void appendTopic() {
		String topic = location.getTopic();
		if (topic != null) {
			User topicAuthor = commandDispatcher.getUserFinder().findUserById(location.getTopicAuthorId());
			ctxSet(DefaultMessageFactory.CTXKEY_VAL, topic);
			if (topicAuthor != null) {
				ctxSet(DefaultMessageFactory.CTXKEY_VAL + "TopicAuthor", topicAuthor.getProperties());
				stringBuffer.append(getString("look.topic", user.getProperties()));
			} else {
				stringBuffer.append(getString("look.noAuthorTopic", user.getProperties()));
			}
		} else {
			stringBuffer.append(getString("look.noTopic", user.getProperties()));
		}
	}
}
